// Copyright 2013 Ronald Schlenker, www.technewlogic.de.
// 
// This file is part of Byond.
// 
// Byond is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
// 
// Byond is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Byond.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.IO;
using Byond.Messages;
using Utils.Messaging;

namespace Byond.EnsembleLibrary
{
	public sealed class Library
	{
		public const string PatchFileExtension = ".byond";

		private readonly Env _env;
		private readonly EnsembleSerializer _ensembleSerializer;

		private void Ctor()
		{
			LibraryDirectory = _env.PatchPath;
			if (!Directory.Exists(LibraryDirectory))
				Directory.CreateDirectory(LibraryDirectory);

			DependenciesDirectory = _env.AssemblyPath;
			if (!Directory.Exists(DependenciesDirectory))
				Directory.CreateDirectory(DependenciesDirectory);
		}

		public event MessageEventHandler SendMessage;

		public string LibraryDirectory { get; private set; }
		public string DependenciesDirectory { get; private set; }

		public LibraryFolder CreateRootFolder()
		{
			return new LibraryFolder(new DirectoryInfo(LibraryDirectory));
		}

		public void DeleteItem(string fileName)
		{
			if (!File.Exists(fileName))
				throw new Exception("Cannot delete library item because it doesn't exist: " + fileName);

			File.Delete(fileName);

			SendMessage(new LibraryChangedMessage());
		}

		public void CreateItem(string directoryName, string patchName)
		{
			var patchFileName = Path.Combine(directoryName, patchName + PatchFileExtension);

			// TODO: Validierungen

			var ensemble = new Ensemble(patchFileName, string.Empty, string.Empty);
			_ensembleSerializer.Save(ensemble);

			SendMessage(new LibraryChangedMessage());
		}

		public void CreateFolder(string path, string folderName)
		{
			Directory.CreateDirectory(Path.Combine(path, folderName));
			SendMessage(new LibraryChangedMessage());
		}

		public void ResetToFactoryDefaults(bool overwriteExisting)
		{
			var sourcePath = Path.GetDirectoryName(GetType().Assembly.Location) + "\\FactoryLibrary";
			var destinationPath = _env.RootPath;

			CopyFolder(sourcePath, destinationPath, overwriteExisting);
			SendMessage(new LibraryChangedMessage());
		}

		private static void CopyFolder(string sourceFolder, string destFolder, bool overwriteExisting)
		{
			if (!Directory.Exists(destFolder))
				Directory.CreateDirectory(destFolder);

			var files = Directory.GetFiles(sourceFolder);
			foreach (var file in files)
			{
				var name = Path.GetFileName(file);
				var dest = Path.Combine(destFolder, name);
				File.Copy(file, dest, overwriteExisting);
			}

			var folders = Directory.GetDirectories(sourceFolder);
			foreach (var folder in folders)
			{
				var name = Path.GetFileName(folder);
				var dest = Path.Combine(destFolder, name);
				CopyFolder(folder, dest, overwriteExisting);
			}
		}
	}
}
